import tkinter as tk
import tkinter.font as tf
from tkinter import messagebox, filedialog, simpledialog, colorchooser
from tkinter import ttk
from PIL import Image, ImageTk

from ToolTip import ToolTip
import sys
import os
import os.path

class MyFrame(tk.Frame):
    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.root = master                 # root
        self.pack(fill=tk.BOTH, expand=True)
        self.font_en = tf.Font(self, size=14)
        if hasattr(sys, '_MEIPASS'):
            # PyInstaller会创建临时文件夹temp，并把路径存储在_MEIPASS中
            self.appPath = sys._MEIPASS
        else:
            self.appPath, filename = os.path.split(os.path.abspath(__file__))

        self.createICO()
        self.create_menu()
        self.createToolbar()
        self.create_widgets()

        self.root.protocol("WM_DELETE_WINDOW", self.on_close)    # 主窗口关闭事件

    # 初始化图标
    def createICO(self):
        self.imgs = []
        self.fileimg = []
        self.fileimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/wenjianjia32.png').resize((24,24))))
        self.fileimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/saveas.png').resize((24,24))))
        self.fileimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/dayin.png').resize((24,24))))
        self.fileimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/guanbi.png').resize((24,24))))
        self.fileimg.append(None)
        self.fileimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/exit.png').resize((24,24))))
        self.imgs.append(self.fileimg)
        self.editimg = []
        self.editimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/charu2.png').resize((24,24))))
        self.editimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/daochu.png').resize((24,24))))
        self.editimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/delete1.png').resize((24,24))))
        self.editimg.append(None)
        self.editimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/zhuanzuo.png').resize((24,24))))
        self.editimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/zhuanyou.png').resize((24,24))))
        self.imgs.append(self.editimg)
        self.viewimg = []
        self.viewimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/fangda.png').resize((24,24))))
        self.viewimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/suoxiao.png').resize((24,24))))
        self.imgs.append(self.viewimg)
        self.helpimg = []
        self.helpimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/help.png').resize((24,24))))
        self.helpimg.append(None)
        self.helpimg.append(ImageTk.PhotoImage(Image.open(self.appPath+'/res/info1.png').resize((24,24))))
        self.imgs.append(self.helpimg)

    # 建立菜单
    def create_menu(self):
        menus = ['   文件', '   编辑',  '   视图', '   帮助']
        items = [['   打开 ...', '   另存为 ...', '   打印', '   关闭文件', '-', '  退出系统'],
                ['   插入', '   导出','   删除', '-', '   左旋转', '   右旋转'],
                ['   放大', '   缩小'],
                ['   帮助', '-', '   关于 ...']]
        callbacks = [[self.onclicked_actionOpen, self.onclicked_actionSaveas, self.onclicked_actionPrint, self.onclicked_actionClose, None, self.onclicked_actionExit],
                     [self.onclicked_actionInsert, self.onclicked_actionExport, self.onclicked_actionDelete, None, self.onclicked_actionRolateLeft, self.onclicked_actionRolateRight],
                [self.onclicked_actionZoomIn, self.onclicked_actionZoomOut],
                [self.onclicked_actionHelp, None, self.onclicked_actionAbout]]
        
        menubar = tk.Menu(self.root)
        for i,x in enumerate(menus):
            m = tk.Menu(menubar, tearoff=0)
            for item, callback, ico in zip(items[i], callbacks[i], self.imgs[i]):
                if isinstance(item, list):    # 如果有二级子菜单（本例没有）
                    sm = tk.Menu(menubar, tearoff=0)
                    for subitem, subcallback, subico in zip(item[1:], callback, ico):
                        if subitem == '-':
                            sm.add_separator()
                        else:
                            sm.add_command(label=subitem, command=subcallback, image=subico, compound='left')
                    m.add_cascade(label=item[0], menu=sm)
                elif item == '-':
                    m.add_separator()
                else:
                    m.add_command(label=item, command=callback, image=ico, compound='left')
            menubar.add_cascade(label=x, menu=m)


        self.root.config(menu=menubar)

    # 生成工具栏
    def createToolbar(self):
        toolframe = ttk.Frame(self, height=20)#, relief=tk.RAISED)
        frame = ttk.Frame(toolframe)
        self.btnOpen = ttk.Button(frame, text="打开一个新PDF文档", width=20, image=self.fileimg[0],command=self.onclicked_actionOpen)
        ToolTip(self.btnOpen)
        self.btnOpen.grid(row=0, column=0, padx=1, pady=1, sticky=tk.E)
        self.btnSaveas = ttk.Button(frame, text="另存为一个新PDF文档", width=20, image=self.fileimg[1], command=self.onclicked_actionSaveas)
        self.btnSaveas.grid(row=0, column=1, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnSaveas)
        self.btnPrint = ttk.Button(frame, text="打印PDF文档", width=20, image=self.fileimg[2], command=self.onclicked_actionPrint)
        self.btnPrint.grid(row=0, column=2, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnPrint)
        self.btnClose = ttk.Button(frame, text="关闭当前PDF文档", width=20, image=self.fileimg[3], command=self.onclicked_actionClose)
        self.btnClose.grid(row=0, column=3, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnClose)
        ttk.Separator(frame,orient='vertical',style='red.TSeparator').grid(row=0, column=4, padx=1, pady=1, sticky=tk.N+tk.S)
        self.btnInsert = ttk.Button(frame, text="将一个PDF文档插入到当前文档", width=20, image=self.editimg[0], command=self.onclicked_actionInsert)
        self.btnInsert.grid(row=0, column=5, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnInsert)
        self.btnExport = ttk.Button(frame, text="将所选页面导出到一个新文档", width=20, image=self.editimg[1], command=self.onclicked_actionExport)
        self.btnExport.grid(row=0, column=6, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnExport)
        self.btnDelete = ttk.Button(frame, text="删除所选页面", width=20, image=self.editimg[2], command=self.onclicked_actionDelete)
        self.btnDelete.grid(row=0, column=7, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnDelete)
        self.btnRolateLeft = ttk.Button(frame, text="逆时针旋转", width=20, image=self.editimg[4], command=self.onclicked_actionRolateLeft)
        self.btnRolateLeft.grid(row=0, column=8, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnRolateLeft)
        self.btnRolateRight = ttk.Button(frame, text="顺时针旋转", width=20, image=self.editimg[5], command=self.onclicked_actionRolateRight)
        self.btnRolateRight.grid(row=0, column=9, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnRolateRight)
        ttk.Separator(frame,orient='vertical',style='red.TSeparator').grid(row=0, column=10, padx=1, pady=1, sticky=tk.N+tk.S)
        self.btnHelp = ttk.Button(frame, text="帮助", width=20, image=self.helpimg[0], command=self.onclicked_actionHelp)
        self.btnHelp.grid(row=0, column=11, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnHelp)
        self.btnAbout = ttk.Button(frame, text="关于...", width=20, image=self.helpimg[2], command=self.onclicked_actionAbout)
        self.btnAbout.grid(row=0, column=12, padx=1, pady=1, sticky=tk.E)
        ToolTip(self.btnAbout)
        frame.pack(side=tk.LEFT)
        toolframe.pack(fill=tk.X)


    
    # 左侧缩略图栏缩放按钮
    def SwitchShowList(self):
        if self.bShowList:
            self.fm_list_scb_ver.pack_forget()
            self.btnShow.config(image=self.imgright)
        else:
            self.fm_list_scb_ver.pack(side=tk.TOP,fill=tk.Y,expand=True)
            self.btnShow.config(image=self.imgleft)

        self.bShowList = not self.bShowList

    # 生成界面元素
    def create_widgets(self):

        self.fm_left = tk.Frame(self)     # 左侧缩略图列表栏
        self.bShowList = True
        self.imgleft =ImageTk.PhotoImage(Image.open(self.appPath+'/res/arrowleft.png').resize((16,16)))
        self.imgright = ImageTk.PhotoImage(Image.open(self.appPath+'/res/arrowright.png').resize((16,16)))
        self.btnShow = tk.Button(self.fm_left,width=16,command=self.SwitchShowList,image=self.imgright)  # 切换labelframe显示\隐藏
        self.btnShow.pack(side=tk.TOP,anchor=tk.E,expand=False)

        # 在LabelFrame中放置label，并带滚动条的方法：
        # 先新建一个canvas，在cavas上放置滚动条，然后在canvas中放置labelframe，frame的长宽，紧跟canvas。
        # 最后canvas.create_window，根据labelframe创建canvas窗口
        self.fm_list_scb_ver = tk.Frame(self.fm_left,width=130)  # 缩略图列表窗口
        vsb1 = tk.Scrollbar(self.fm_list_scb_ver,width=10)    # canvas垂直滚动条
        vsb1.pack(side=tk.RIGHT,fill=tk.Y)
        self.listCanvas = tk.Canvas(self.fm_list_scb_ver,bg = 'white',yscrollcommand=vsb1.set,width=120)  # 缩略图放置canvas
        self.listCanvas.pack(side=tk.LEFT,fill=tk.BOTH, expand=True)
        vsb1.config(command=self.listCanvas.yview)

        self.labelframe = tk.LabelFrame(self.listCanvas)  # 把labelframe放在canvas里
        self.labelframe.pack(fill=tk.BOTH,expand=True)  # labelframe的长宽，和canvas差不多的

        self.fm_list_scb_ver.pack(side=tk.TOP,fill=tk.Y,expand=True)    #放置缩略图列表窗口
        self.fm_left.pack(side=tk.LEFT,fill=tk.Y)    # 放置左侧缩略图列表栏

        self.fm_right = tk.Frame(self)    # 右侧查看窗口
        self.fm_canvas_scb_ver = tk.Frame(self.fm_right)  # canvas放置窗口
        vsb = tk.Scrollbar(self.fm_canvas_scb_ver)    # canvas滚动条
        vsb.pack(side=tk.RIGHT,fill=tk.Y) 
        hsb = tk.Scrollbar(self.fm_canvas_scb_ver,orient=tk.HORIZONTAL) 
        hsb.pack(side=tk.BOTTOM,fill=tk.X)
        # 创建canvas，并绑定滚动条
        self.cvCanvas = tk.Canvas(self.fm_canvas_scb_ver,bg = 'white',yscrollcommand=vsb.set,xscrollcommand=hsb.set,scrollregion=(0,0,1200,1200))
        self.cvCanvas.pack(fill=tk.BOTH, expand=True)
        self.cvCanvas.bind("<Control-MouseWheel>", self.canvasProcessWheel)   # 鼠标滚轮事件 CTRL + 滚轮
        vsb.config(command=self.cvCanvas.yview)
        hsb.config(command=self.cvCanvas.xview)
        self.fm_canvas_scb_ver.pack(fill=tk.BOTH, expand=True)  # 放置canvas放置窗口
        self.fm_right.pack(fill=tk.BOTH, expand=True)   # 放置右侧查看窗口

        # Status bar
        self.status_var = tk.StringVar()
        self.status_var.set("Ready")
        status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W)
        status_bar.pack(side=tk.BOTTOM,fill=tk.X)

    # Update status
    def UpdateStatus(self, text):
        self.status_var.set(text)
        self.root.update()

    # 更新窗口标题
    def UpdateRootTitle(self, text):
        self.root.title(f'Simple PDF Tool - {text}')
        self.root.update_idletasks()

    # 主窗口关闭
    def on_close(self):
        self.root.quit()
        self.root.destroy()
